package com.ww.java.generic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// 层次结构定义
class LivingBeing {
}

class Animal extends LivingBeing {
    public void eat() {
        System.out.println("Animal eating");
    }
}

class Mammal extends Animal {
    public void breathe() {
        System.out.println("Mammal breathing");
    }
}

class Dog extends Mammal {
    public void bark() {
        System.out.println("Dog barking");
    }
}

class Cat extends Mammal {
    public void meow() {
        System.out.println("Cat meowing");
    }
}

public class VarianceDemo {
    // 协变示例- 生产者，只读
    public static void printAllAnimals(List<? extends Animal> animals) {
        System.out.println("=== Printing animals ===");
        for (Animal animal : animals) {
            animal.eat();
            if (animal instanceof Mammal) {
                ((Mammal) animal).breathe();
            }
        }
    }

    // 逆变示例- 消费者，只写
    public static void addMammals(List<? super Mammal> mammals) {
        System.out.println("=== Adding mammals ===");
        mammals.add(new Dog());
        mammals.add(new Cat());
        mammals.add(new Mammal());
//        mammals.add(new LivingBeing()); // 只能添加Mammal及其子类
    }

    // PECS原则应用
    public static void copyAnimals(List<? extends Animal> source,
                                   List<? super Animal> destination) {
        System.out.println("=== Copying animals ===");
        for (Animal animal : source) {
            destination.add(animal);
        }
    }

    // 打印结果
//    === Printing animals ===
//    Animal eating
//    Mammal breathing
//    Animal eating
//    Mammal breathing
//    === Printing animals ===
//    Animal eating
//    Mammal breathing
//    Animal eating
//    Mammal breathing
//    === Printing animals ===
//    === Printing animals ===
//    === Adding mammals ===
//    === Adding mammals ===
//    === Adding mammals ===
//    === Adding mammals ===
//    === Copying animals ===
//    === Copying animals ===
//    === Copying animals ===
    public static void main(String[] args) {
        // 创建不同层次的列表
        List<Dog> dogs = Arrays.asList(new Dog(), new Dog());
        List<Cat> cats = Arrays.asList(new Cat(), new Cat());
        List<Mammal> mammals = new ArrayList<>();
        List<Animal> animals = new ArrayList<>();
        List<LivingBeing> beings = new ArrayList<>();
        List<Object> objects = new ArrayList<>();

        // 测试协变
        printAllAnimals(dogs);
        printAllAnimals(cats);
        printAllAnimals(mammals);
        printAllAnimals(animals);

        // 测试逆变
        addMammals(mammals);
        addMammals(animals);
        addMammals(beings);
        addMammals(objects);

        // 测试PECS
        copyAnimals(dogs, animals); // 从Dog列表读到Animal列表
        copyAnimals(cats, beings); // 从Cat列表读到LivingBeing列表
        copyAnimals(mammals, objects); // 从Mammal列表读到Object列表
    }
}
